#include "components/controlclass/graphicsprocess/svgcanvas/svgcanvas.h"
#include <QColor>
#include <QKeyEvent>
#include <QDebug>
#include <kernel/shape/svgline.h>
#include <kernel/shape/svgrectangle.h>
#include <kernel/shape/svgellipse.h>
#include "kernel/shape/svgfreeline.h"

SvgCanvas::SvgCanvas(QWidget* parent /*= nullptr*/):QWidget(parent)
	,m_color(QColor("#ffffff"))
	,isMoveCanvas(false)
	, isPressMouse(false)
	, m_shape(Shape::ShapeType::select)
	, m_scaling(1)
	,isDrawCanvans(false)
	, isStrchShape(false)
	,m_indexSelected(-1)
	,m_size(500,500)
	,m_penColor("#000000")
	,m_penWidth(2)
	,m_penStyle(Qt::SolidLine)
	,m_fillColor("#ffffff")
	, m_nums(0)
	,m_multipleChoice(false)
	,m_isMultipleChoice(false)
	,isDisableEdit(false)
	, m_isDrawGrid(false)
{
	
	initWidget();
	initSignals();
}

SvgCanvas::~SvgCanvas()
{

}

void SvgCanvas::isOpenGrid(bool flags)
{
	m_isDrawGrid = flags;
	update();
}

void SvgCanvas::setBackgroundColor(const QColor& color)
{
	m_color = color;
	QPalette palette;
	palette.setColor(QPalette::Background, color);
	this->setPalette(palette);
	this->setAutoFillBackground(true);

}

void SvgCanvas::setCurShape(const Shape::ShapeType shape)
{
	m_shape = shape;
}

void SvgCanvas::changeSize(const QSize& size)
{
	move(this->pos().x() + (this->size().width() - size.width()) / 2, this->pos().y() + (this->size().height() - size.height()) / 2);
	this->setFixedSize(size);
	m_scaling = 1.0;
	emit sendCanvasScaling(m_scaling);
	m_size = size;
}

void SvgCanvas::setScaling(const double& scaling)
{
	zoomSize(scaling, QPointF(0,0));
}

void SvgCanvas::zoomSize(const double& scaling, const QPointF& clickPos)
{
	if ((5 <= m_scaling && scaling > m_scaling) || (0.2 >= m_scaling && scaling < m_scaling)) return;
	QPointF mpos = geometry().topLeft();
	double mx = clickPos.x() * (1 - scaling / m_scaling);
	double my = clickPos.y() * (1 - scaling / m_scaling);
	m_scaling = scaling;
	this->setFixedSize(m_size.width() * m_scaling, m_size.height() * m_scaling);
	emit sendSlcaing(m_scaling);
	this->move(mpos.x() + mx, mpos.y() + my);
	update();
}

void SvgCanvas::setSelectShapesTrans(const int& value)
{
	m_shapeList[m_indexSelected]->setOpacity(value);
	update();
}

void SvgCanvas::setSelectShapesfillColor(const QColor& color)
{
	m_shapeList[m_indexSelected]->setBackgroundColor(color);
	update();
}

void SvgCanvas::setSelectShapsStrokeColor(const QColor& color)
{
	m_shapeList[m_indexSelected]->setBorderColor(color);
	update();
}

void SvgCanvas::setSelectedShape(const Shape::ShapeType shape)
{
	
	switch (shape)
	{
	case Shape::ShapeType::line: {}break;
	case Shape::ShapeType::freeLine: {}break;

	case Shape::ShapeType::rectangle:
	case Shape::ShapeType::circle:
	case Shape::ShapeType::ellipse:
	{

		emit sendShapeSelected(2,m_shapeList[m_indexSelected]->getRectW(), m_shapeList[m_indexSelected]->getRectH(),
			m_shapeList[m_indexSelected]->getPositionX(), m_shapeList[m_indexSelected]->getPositionY(), 
			m_shapeList[m_indexSelected]->getRatotion(), m_shapeList[m_indexSelected]->getOpacity(),
			m_shapeList[m_indexSelected]->getBlur(), m_shapeList[m_indexSelected]->getBackgroundColor(),
			m_shapeList[m_indexSelected]->getBorderColor()
			);
		update();
	}
	break;
	default:
		break;
	}
}

void SvgCanvas::mouseMoveEvent(QMouseEvent* event)
{
	//this->setCursor(Qt::SizeAllCursor);
	if (m_shape == Shape::ShapeType::shapeZoom) {
		QCursor myCursor(QPixmap(":/cursor/res/icons/ui/control/mousercurosr/zoomshape.png"), -1, -1);
		this->setCursor(myCursor);

	}
	else
	{
		//this->setCursor(Qt::ArrowCursor);
	}
	if (isMoveCanvas&& isSpaceKeyPress&& isPressMouse&& m_shape == Shape::ShapeType::select) {
		this->setCursor(Qt::ClosedHandCursor);
		m_endPos = event->localPos();
		int mx = this->pos().x() + m_endPos.x() - m_stPos.x();
		int my = this->pos().y() + m_endPos.y() - m_stPos.y();
		this->move(mx, my);
		update();
		return;
	}
	if (isPressMouse && !isMoveCanvas)
	{
		m_lastPos = m_endPos;
		m_endPos = event->localPos() / m_scaling;
		switch (m_shape)
		{
		case Shape::ShapeType::select:
		{
			if (m_multipleChoice)
			{
				m_selectRect.moveSelectedShaps(m_endPos.x() - m_lastPos.x(), m_endPos.y() - m_lastPos.y());
			}
			else
			{
				if (isStrchShape && -1 < m_indexSelected)
				{
					m_surroundGraph.changeGraph(m_shapeList[m_indexSelected], m_selectPos, m_lastPos, m_endPos);
					setSelectedShape(m_shapeList[m_indexSelected]->getShapeType());
				}
				else if (!isStrchShape && -1 < m_indexSelected)
				{
					selectedShapesMoveTo(m_endPos.x() - m_lastPos.x(), m_endPos.y() - m_lastPos.y());
					setSelectedShape(m_shapeList[m_indexSelected]->getShapeType());
				}
				else
				{
					m_isMultipleChoice = true;
					m_path.clear();
					m_path.push_back(m_stPos);
					m_path.push_back(m_endPos);
					m_selectRect.setPath(m_path);
				}
				update();
			}
		}
		break;
		case Shape::ShapeType::line:
		{
			m_path.clear();
			m_path.push_back(m_stPos);
			m_path.push_back(m_endPos);
			m_shapeList[m_nums - 1]->setPath(m_path);
			update();
		}
		break;

		case Shape::ShapeType::freeLine:
		{
			m_path.push_back(m_endPos);
			m_shapeList[m_nums - 1]->setPath(m_path);
			update();
		}
		break;
		case Shape::ShapeType::rectangle:
		{
			m_path.clear();
			m_path.push_back(m_stPos);
			m_path.push_back(m_endPos);
			m_shapeList[m_nums - 1]->setPath(m_path);
			update();
		}
			break;
		case Shape::ShapeType::circle: {
	
				m_path.clear();
				m_path.push_back(m_stPos);
				m_path.push_back(m_endPos);
				m_shapeList[m_nums - 1]->setPath(m_path);
				update();
		}
			break;
		case Shape::ShapeType::ellipse:
			break;
		case Shape::ShapeType::polyline:
			break;
		case Shape::ShapeType::polygon:
			break;
		case Shape::ShapeType::path:
			break;
		case Shape::ShapeType::text:
			break;
		case Shape::ShapeType::eyedroper:
			break;
		case Shape::ShapeType::shapeZoom:
		{
			QCursor myCursor(QPixmap(":/cursor/res/icons/ui/control/mousercurosr/zoomshape.png"), -1, -1);
			this->setCursor(myCursor);
		}
			break;
		default:
			break;
		}
	}
	if (!isPressMouse && !isStrchShape && !isMoveCanvas) 
	{
		m_endPos = event->localPos();
		setSelectCursor(m_surroundGraph.graphChangeClicked(m_endPos));
	}
}

void SvgCanvas::mousePressEvent(QMouseEvent* event)
{
	m_stPos = event->localPos();
	m_lastPos = m_stPos;
	m_endPos = m_stPos;
	isPressMouse = true;
	if (isMoveCanvas&& isSpaceKeyPress&& m_shape == Shape::ShapeType::select) {
		this->setCursor(Qt::ClosedHandCursor);
		return;
	}
	if (Qt::LeftButton == event->button() && !isMoveCanvas) {
		isPressMouse = true;
		m_stPos = event->localPos() / m_scaling;
		m_endPos = m_stPos;
		switch (m_shape)
		{
		case Shape::ShapeType::select:
		{
			if (m_multipleChoice) {
				m_multipleChoice = m_selectRect.containsPointF(m_stPos);
			}
			else
			{
				isStrchShape = m_surroundGraph.containsClicked(event->localPos());
				if (isStrchShape) {
					m_selectPos = m_surroundGraph.graphChangeClicked(event->localPos());
				}
				else
				{
					m_indexSelected = shapeIsSelected(m_stPos);
					if (-1 != m_indexSelected) {
						setSelectedShape(m_shapeList[m_indexSelected]->getShapeType());
					}
					else
					{
						emit sendSelectCanvas();
					}
					
				}
			}
			update();

		}
			break;
		case Shape::ShapeType::line:
		{
			this->setCursor(Qt::CrossCursor);
			m_path.clear();
			Shape::SvgAbstractShape* m_shape = new Shape::SvgLine();
			m_path.push_back(m_stPos);
			m_path.push_back(m_endPos);
			m_shape->setPath(m_path);
			addShapeToCanvas(m_shape);
			m_shape = nullptr;
			update();
		}
			break;
		case Shape::ShapeType::rectangle:
		{

			this->setCursor(Qt::CrossCursor);
			m_path.clear();
			Shape::SvgAbstractShape* m_shape = new Shape::SvgRectangle();
			m_path.push_back(m_stPos);
			m_path.push_back(m_endPos);
			m_shape->setPath(m_path);
			addShapeToCanvas(m_shape);
			m_shape = nullptr;
			update();
		}
			break;
		case Shape::ShapeType::freeLine:
		{
			this->setCursor(Qt::CrossCursor);
			m_path.clear();
			Shape::SvgAbstractShape* shape = new Shape::SvgFreeLine();
			m_path.push_back(m_stPos);
			m_path.push_back(m_endPos);
			shape->setPath(m_path);
			addShapeToCanvas(shape);
			shape = nullptr;
		}
		break;
		case Shape::ShapeType::circle:
		{
			this->setCursor(Qt::CrossCursor);
			m_path.clear();
			Shape::SvgAbstractShape* shape = new Shape::SvgEllipse();
			m_path.push_back(m_stPos);
			m_path.push_back(m_endPos);
			shape->setPath(m_path);
			addShapeToCanvas(shape);
			shape = nullptr;
		}
			break;
		case Shape::ShapeType::ellipse:
		
			break;
		case Shape::ShapeType::polyline:
			break;
		case Shape::ShapeType::polygon:
			break;
		case Shape::ShapeType::path:
			break;
		case Shape::ShapeType::text:
			break;
		case Shape::ShapeType::eyedroper:
			break;
		case Shape::ShapeType::shapeZoom:
		{
			QCursor myCursor(QPixmap(":/cursor/res/icons/ui/control/mousercurosr/zoomshape.png"), -1, -1);
			this->setCursor(myCursor);
		}
		break;
		default:
			break;
		}
	}
}

void SvgCanvas::mouseReleaseEvent(QMouseEvent* event)
{
	
	isMovePress = false;
	if (isMoveCanvas) {
		//isMoveCanvas
	
		this->setCursor(Qt::OpenHandCursor);
	}
	if (Qt::LeftButton == event->button() && isPressMouse && !isMoveCanvas)
	{
		m_endPos = event->localPos() / m_scaling;
		switch (m_shape)
		{
		case Shape::ShapeType::select: {
			isStrchShape = false;
			if (m_isMultipleChoice)
			{
				m_selectRect.clear();
				m_isMultipleChoice = false;
				m_selectRect.selectedShapes(m_shapeList);
				if (0 < m_selectRect.getGraphsNums())
					m_multipleChoice = true;
			}
			update();
		}
			break;
		case Shape::ShapeType::line:
		{
		/*	m_shapeList.first()->setEndPosition(m_endPos);*/
			//m_shapeList.first()->setDrawend(true);
		}
			break;
		case Shape::ShapeType::rectangle:
			break;
		case Shape::ShapeType::circle:
			break;
		case Shape::ShapeType::ellipse:
			break;
		case Shape::ShapeType::polyline:
			break;
		case Shape::ShapeType::polygon:
			break;
		case Shape::ShapeType::path:
			break;
		case Shape::ShapeType::text:
			break;
		case Shape::ShapeType::eyedroper:
			break;
		default:
			break;
		}
		isPressMouse = false;
	}
	
}

void SvgCanvas::wheelEvent(QWheelEvent* event)
{
	if (isDisableEdit) {
		return;
	}
	switch (m_shape)
	{
	case Shape::ShapeType::select:
	{
		if (-1==m_indexSelected)
		{
			return;
		}
		if (0 < event->delta()) {
			m_shapeList[m_indexSelected]->setRatotion(m_shapeList[m_indexSelected]->getRatotion() + 1);
			
		}
		else
		{
			m_shapeList[m_indexSelected]->setRatotion(m_shapeList[m_indexSelected]->getRatotion() - 1);
		}
		update();


	}
		break;
	case Shape::ShapeType::shapeZoom:
	{
		if (0 < event->delta()) {
			zoomSize(m_scaling * 1.1, event->posF());
		}
		else
		{
			zoomSize(m_scaling / 1.1, event->posF());
			qDebug() << "ssssssssssssss0";
		}
		emit sendCanvasScaling(m_scaling);

	}
		break;
	}
}

void SvgCanvas::paintEvent(QPaintEvent* event)
{
	QPainter* p = new QPainter;
	p->begin(this);
	p->setRenderHint(QPainter::Antialiasing);
	if (m_isDrawGrid) {
		m_grid.setSize(this->width(), this->height());
		m_grid.paintGrid(*p);
	}
	for (auto it : m_shapeList) {
		it->drawShape(p, m_scaling);
	}
	if (-1 < m_indexSelected) {
		m_surroundGraph.setRect(m_shapeList[m_indexSelected]->getRectF(), m_scaling);
		m_surroundGraph.setRotate(m_shapeList[m_indexSelected]->getRatotion());
		m_surroundGraph.paintSurroundRect(p);
	}

	m_selectRect.paintRect(*p, QPen(1),m_isMultipleChoice, m_scaling);
	m_selectRect.paintSelectedGraphRect(*p, QPen(1),m_multipleChoice,m_scaling);
	p->end();
}

void SvgCanvas::resizeEvent(QResizeEvent* event)
{

}

void SvgCanvas::keyPressEvent(QKeyEvent* event)
{
	switch (event->key())
	{
	case Qt::Key_Space:
		if (!event->isAutoRepeat() && !isMoveCanvas) {
			isMoveCanvas = true;
			isPressMouse = false;
			isSpaceKeyPress = true;
			this->setCursor(Qt::OpenHandCursor);
		}
		break;
	default:
		break;
	}
}

void SvgCanvas::keyReleaseEvent(QKeyEvent* event)
{
	switch (event->key())
	{
	case Qt::Key_Space:
		if (isMoveCanvas && !event->isAutoRepeat()) {
			isMoveCanvas = false;
			this->setCursor(Qt::ArrowCursor);
		}
		break;
	default:
		break;
	}
}

void SvgCanvas::initWidget()
{
	setFocusPolicy(Qt::ClickFocus);
	//this->setAttribute(Qt::WA_TransparentForMouseEvents, true);
	//this->setFocusPolicy(Qt::NoFocus);
	this->setMouseTracking(true);
	this->setFixedSize(500, 500);
	setBackgroundColor(m_color);
	//this->setMouseTracking(true);
	this->setFocus();
}

void SvgCanvas::initSignals()
{

}

void SvgCanvas::addShapeToCanvas(Shape::SvgAbstractShape* drawgraph)
{
	m_shapeList.push_back(drawgraph);
	++m_nums;
	m_indexSelected = m_nums - 1;
	setSelectedShape(m_shapeList[m_indexSelected]->getShapeType());
	update();
}

int SvgCanvas::shapeIsSelected(const QPointF& point)
{
	for (int i = m_nums - 1; i >= 0; --i)
		if (m_shapeList[i]->isContains(point))
			return i;
	return -1;
}

void SvgCanvas::selectedShapesMoveTo(const double& x, const double& y)
{
	if (-1 != m_indexSelected)
		m_shapeList[m_indexSelected]->moveTo(x, y);
}

void SvgCanvas::setSelectCursor(const SelectRegion::SelectPos& selectPos)
{
	if (Shape::ShapeType::select != m_shape)
	{
		return;
	}
	this->setCursor(Qt::ArrowCursor);
	if (0 > m_indexSelected) return;
	double rotate = m_shapeList[m_indexSelected]->getRatotion();
	if (rotate < 0)
	{
		rotate += 360;
	}
	rotate = int(rotate) % 180;
	switch (selectPos)
	{
	case SelectRegion::SelectPos::TopLeft:
	{
		if (30 > rotate)
			this->setCursor(Qt::SizeFDiagCursor);
		else if (30 <= rotate && 60 > rotate)
			this->setCursor(Qt::SizeVerCursor);
		else if (60 <= rotate && 120 > rotate)
			this->setCursor(Qt::SizeBDiagCursor);
		else if (120 <= rotate && 150 > rotate)
			this->setCursor(Qt::SizeHorCursor);
		else
			this->setCursor(Qt::SizeFDiagCursor);
		break;
	}
	break;
	case SelectRegion::SelectPos::TopMid:
	{
		if (30 > rotate)
			this->setCursor(Qt::SizeVerCursor);
		else if (30 <= rotate && 60 > rotate)
			this->setCursor(Qt::SizeBDiagCursor);
		else if (60 <= rotate && 120 > rotate)
			this->setCursor(Qt::SizeHorCursor);
		else if (120 <= rotate && 150 > rotate)
			this->setCursor(Qt::SizeFDiagCursor);
		else
			this->setCursor(Qt::SizeVerCursor);
	}
	break;
	case	SelectRegion::SelectPos::TopRight:
	{
		if (30 > rotate)
			this->setCursor(Qt::SizeBDiagCursor);
		else if (30 <= rotate && 60 > rotate)
			this->setCursor(Qt::SizeHorCursor);
		else if (60 <= rotate && 120 > rotate)
			this->setCursor(Qt::SizeFDiagCursor);
		else if (120 <= rotate && 150 > rotate)
			this->setCursor(Qt::SizeVerCursor);
		else
			this->setCursor(Qt::SizeBDiagCursor);
	}
	break;

	case	SelectRegion::SelectPos::MidLeft:
	{
		if (30 > rotate)
			this->setCursor(Qt::SizeHorCursor);
		else if (30 <= rotate && 60 > rotate)
			this->setCursor(Qt::SizeFDiagCursor);
		else if (60 <= rotate && 120 > rotate)
			this->setCursor(Qt::SizeVerCursor);
		else if (120 <= rotate && 150 > rotate)
			this->setCursor(Qt::SizeBDiagCursor);
		else
			this->setCursor(Qt::SizeHorCursor);
	}
	break;
	case	SelectRegion::SelectPos::MidRight:
	{
		if (30 > rotate)
			this->setCursor(Qt::SizeHorCursor);
		else if (30 <= rotate && 60 > rotate)
			this->setCursor(Qt::SizeFDiagCursor);
		else if (60 <= rotate && 120 > rotate)
			this->setCursor(Qt::SizeVerCursor);
		else if (120 <= rotate && 150 > rotate)
			this->setCursor(Qt::SizeBDiagCursor);
		else
			this->setCursor(Qt::SizeHorCursor);
	}
	break;

	case	SelectRegion::SelectPos::BottomLeft:
	{
		if (30 > rotate)
			this->setCursor(Qt::SizeBDiagCursor);
		else if (30 <= rotate && 60 > rotate)
			this->setCursor(Qt::SizeHorCursor);
		else if (60 <= rotate && 120 > rotate)
			this->setCursor(Qt::SizeFDiagCursor);
		else if (120 <= rotate && 150 > rotate)
			this->setCursor(Qt::SizeVerCursor);
		else
			this->setCursor(Qt::SizeBDiagCursor);
	}
	break;
	case	SelectRegion::SelectPos::BottomMid:
	{
		if (30 > rotate)
			this->setCursor(Qt::SizeVerCursor);
		else if (30 <= rotate && 60 > rotate)
			this->setCursor(Qt::SizeBDiagCursor);
		else if (60 <= rotate && 120 > rotate)
			this->setCursor(Qt::SizeHorCursor);
		else if (120 <= rotate && 150 > rotate)
			this->setCursor(Qt::SizeFDiagCursor);
		else
			this->setCursor(Qt::SizeVerCursor);
	}
	break;
	case	SelectRegion::SelectPos::BottomRight:
	{
		if (30 > rotate)
			this->setCursor(Qt::SizeFDiagCursor);
		else if (30 <= rotate && 60 > rotate)
			this->setCursor(Qt::SizeVerCursor);
		else if (60 <= rotate && 120 > rotate)
			this->setCursor(Qt::SizeBDiagCursor);
		else if (120 <= rotate && 150 > rotate)
			this->setCursor(Qt::SizeHorCursor);
		else
			this->setCursor(Qt::SizeFDiagCursor);
	}
	break;
	case	SelectRegion::SelectPos::RotatePos:
	{
		QCursor myCursor(QPixmap(":/res/image/rotatemouse.svg"), -1, -1);
		this->setCursor(Qt::PointingHandCursor);
	}
	break;
	case	SelectRegion::SelectPos::UselessPos:
	{
		this->setCursor(Qt::ArrowCursor);
	}
	break;
	default:
		break;
	}

}

